package com.ruijie.acl.service;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Property;
import org.hibernate.criterion.Restrictions;
import org.jboss.seam.annotations.Transactional;
import org.springframework.util.Assert;

import com.ruijie.acl.AccessGroup;
import com.ruijie.acl.Ace;
import com.ruijie.acl.AclDevice;
import com.ruijie.acl.AclDeviceAccessGroup;
import com.ruijie.acl.AclInterface;
import com.ruijie.acl.TimeInfo;
import com.ruijie.acl.TimeRange;
import com.ruijie.acl.task.config.TaskConfigAclDevice;
import com.ruijie.acl.task.model.AccessGroupInfo;
import com.ruijie.acl.task.model.AclDeviceInfo;
import com.ruijie.acl.task.model.AclInterfaceInfo;
import com.ruijie.acl.utils.AclConfigUtil;
import com.ruijie.acl.utils.AclEntityUtil;
import com.ruijie.acl.utils.AclUtil;
import com.ruijie.batch.plan.PlanParameters;
import com.ruijie.emp.device.Device;
import com.ruijie.foundation.dao.support.Page;
import com.ruijie.foundation.exception.BusinessException;
import com.ruijie.foundation.international.web.function.MessageFunctionLibrary;
import com.ruijie.foundation.utils.StringUtils;

public class AccessGroupServiceImpl extends
		AclHibernateEntityExtendDao<AccessGroup> implements AccessGroupService {
	
	private TimeRangeService timeRangeService;
	private TimeInfoService timeInfoService;
	private AceService aceService;
	private AclPlanParametersService parametersService;
	private AclInterfaceService aclInterfaceService;
	private TaskConfigAclDevice taskConfigAclDevice;
	private DeviceTimeRangeService deviceTimeRangeService;
	
	private DeviceAccessGroupService deviceAccessGroupService;
	private AclDeviceService aclDeviceService;

	public AclInterfaceService getAclInterfaceService() {
		return aclInterfaceService;
	}

	public void setAclInterfaceService(AclInterfaceService aclInterfaceService) {
		this.aclInterfaceService = aclInterfaceService;
	}

	/**
	 * 分页查询
	 * 
	 * @param access
	 *            ACL组
	 * @param pageNo
	 *            页数
	 * @param pageSize
	 *            每页显示的记录数
	 * @return ACL组列表
	 */
	@Override
	public Page pageQuery(AccessGroup accessGroup, int pageNo, int pageSize) {
		Assert.notNull(accessGroup);
		Criteria criteria = createCriteria(AccessGroup.class);
		if (!StringUtils.isNullOrEmpty(accessGroup.getName())) {
			Criterion nameCriterion = Restrictions.like("name", accessGroup
					.getName(), MatchMode.ANYWHERE);
			criteria.add(nameCriterion);
		}
		if (!StringUtils.isNullOrEmpty(accessGroup.getAclType())) {
			Criterion genreCriterion = Restrictions.eq("aclType", accessGroup
					.getAclType());
			criteria.add(genreCriterion);
		}
		if (accessGroup.getIsChanged() != null) {
			Criterion isChangedCriterion = null;
			if (accessGroup.getIsChanged()) {
				isChangedCriterion = Restrictions.eq("isChanged", accessGroup
						.getIsChanged());
			} else {
				isChangedCriterion = Restrictions.or(Restrictions.eq(
						"isChanged", accessGroup.getIsChanged()), Restrictions
						.isNull("isChanged"));
			}
			criteria.add(isChangedCriterion);

		}
		criteria.add(Restrictions.like("deleteFlg", false));
		// 且不是导入的设备组。



		criteria.add(Restrictions.isNull("aclDevice"));
		return pagedQuery(criteria, pageNo, pageSize);
	}

	/**
	 * 从文本中导入ACL组信息

	 * 
	 * @param acldevice　acl设备
	 * @return 返回导入的失败信息

	 */
	@Transactional
	public List<String[]> loadAccessGroup(AclDeviceInfo deviceInfo){
		try {
			List<AccessGroupInfo> groupList = deviceInfo.getAccessGroupInfoList();
			if(groupList.size()==0){
				throw new BusinessException(MessageFunctionLibrary.i18n_msg("acl_group_import_dataerror").toString());
			}
			/*保存时间段*/
			List<TimeRange> timeRangeList = AclEntityUtil.timeRangeInfoList2TimeRangeList(deviceInfo.getTimeRangeInfoList());
			List<String[]> timeRangeResult = saveTimeRangeInfo2TimeRange(timeRangeList);
			this.getSessionFactory().getCurrentSession().flush();
			/*保存ACL组*/
			//遍历AccessGroupInfo处理
			//取得AccessGroup信息
			List<AccessGroup> accessGroupList = AclEntityUtil.accessGroupInfoList2AccessGroupList(groupList);
			//导入组的提示信息
			List<String[]> importResult=new ArrayList<String[]>();
			importResult.addAll(timeRangeResult);
			//[start]判断导入组中，是否存在同名

			List<String> allGroups=new ArrayList<String>();
			for(int i=0;i<accessGroupList.size();i++){
				String name=accessGroupList.get(i).getName();
				String validateResult = AclUtil.validateGroupName(name,accessGroupList.get(i).getAclType());
				if(validateResult.length()>0){
					if("acl_group_maxlength".equals(validateResult)){
						throw new BusinessException(validateResult);
					}else{
						throw new BusinessException(validateResult+"_group",name);
					}
					
				}
				if(allGroups.contains(name)||name==null){
					throw new BusinessException("acl_group_import_nameExites");
				}else{
					allGroups.add(name);
				}
			}
			//[end]
			for(AccessGroup accessGroup:accessGroupList){
				int orign=accessGroup.getAces().size();
				List<String[]> result=AclUtil.filterAndValidateAccessGroup(accessGroup);
				int successCount=accessGroup.getAces().size();
				int failtCount=orign-successCount;
				//导入ACL组：{0}，成功导入规则{1}条，失败{2}条。

				importResult.add(new String[]{
						"acl_group_ace_import_info",
						accessGroup.getName(),
						new Integer(successCount).toString(),
						new Integer(failtCount).toString()
						});
				if(result!=null&&result.size()>0){
					importResult.addAll(result);
				}
			}
			
			saveAccessGroupList(accessGroupList);
			return importResult.size()>0?importResult:null;
		}catch (BusinessException bex) {
			throw bex;
		} catch (Exception ex) {
			throw new BusinessException(ex.getMessage());
		}
	}
	
	/**
	 * 保存ACL组信息



	 * @param list 设备的ACL组列表



	 * @param aclDevice ACL设备
	 */
	public void saveAccessGroupList(List<AccessGroup> accessGroupList){
		if (accessGroupList != null && accessGroupList.size() > 0){
			for (AccessGroup entity : accessGroupList){
				boolean existAccessGroup = false;
				List<Ace> aceList = entity.getAces();
				if (aceList == null){
					aceList = new ArrayList<Ace>();
				}
				if (aceList.size() > 0 && aceList.get(0) == null){
					aceList.remove(0);
				}
				//进行DB存在验证AccessGroup
				List<AccessGroup> dbAccessGroupList = getAccessGroupByName(entity.getName());
				if(dbAccessGroupList.size()>0){
					existAccessGroup = true;
				}
				if (!existAccessGroup){
					//不存在时
					//保存AccessGroup
					entity.setAces(null);
					entity.setIsChanged(false);
					entity.setDeleteFlg(false);
					save(entity);
					//保存所有ACE
					for (Ace ace : aceList){
						//判断TimeRange是否存在(根据name)
						TimeRange tr = null;
						if (ace.getTimeRangeName() != null){
							tr = timeRangeService.getByNameWithoutAclDevice(ace.getTimeRangeName());
						}
						//存在则设置TimeRange对象
						//不存在时设置TimeRange为null 
						AclUtil.filterAce(ace, entity.getAclType());
						ace.setTimeRange(tr);
						ace.setAccessGroup(entity);
						aceService.save(ace);
					}
				}else{
					throw new BusinessException(MessageFunctionLibrary.i18n_msg("acl_group_import_nameExites").toString());
				}
			}
		}
	}
	
	/**
	 * 保存时间段信息
	 * @param timeRangeList 设备的时间段列表
	 */
	public List<String[]> saveTimeRangeInfo2TimeRange(List<TimeRange> timeRangeList){
		//遍历TimeRangeInfo处理
		//取得TimeRange信息
		List<String[]> validaterInfos=new ArrayList<String[]>();
		if (timeRangeList != null && timeRangeList.size() > 0){
			for (TimeRange entity : timeRangeList){
				boolean existTimeRange = false;
				List<TimeInfo> timeInfoList = entity.getTimeInfoList();
				if (timeInfoList == null){
					timeInfoList = new ArrayList<TimeInfo>();
				}
				//进行验证TimeRange
				List<TimeRange> dbTimeRangeList = timeRangeService.getByName(entity.getName());
				if (dbTimeRangeList != null && dbTimeRangeList.size() > 0){
					existTimeRange = true;
					validaterInfos.add(new String[]{"acl_group_timeRange_import_info_repeat",entity.getName()});
				}
				if (!existTimeRange){
					//不存在时
					//保存TimeRange
					timeRangeService.save(entity);
					int allTimeInfoCount = timeInfoList.size();//所有timeInfo的条数
					if(entity.getStartDate()!=null || entity.getEndDate()!=null){
						allTimeInfoCount++;
					}
					int errorCount = 0;//错误的timeInfo条数
					/*验证abstactTimeInfo的正确性获得错误信息*/
					if(entity.getStartDate()!=null && entity.getEndDate()!=null){
						Calendar startCalendar = Calendar.getInstance();
						startCalendar.setTime(entity.getStartDate());
						Calendar endCalendar = Calendar.getInstance();
						endCalendar.setTime(entity.getEndDate());
						// 开始时间不能大于或者等于结束时间
						if (startCalendar.compareTo(endCalendar) >= 0) {
							validaterInfos.add(new String[]{"acl_link_used_error_single"});
						}
					}
					
					/*验证TimeInfo的正确性获得错误信息*/
					List<TimeInfo> tempTimeInfo = new ArrayList<TimeInfo>();
					List<String[]> timeInfoResult =new ArrayList<String[]>();
					for (int i=0;i<timeInfoList.size();i++){
						if(tempTimeInfo.indexOf(timeInfoList.get(i))>=0 ){
							errorCount++;
							timeInfoResult.add(new String[]{"acl_group_timeInfo_import_failed_filter",new Integer(i+1).toString(),"acl_group_timeInfo_repeat"});
							continue;
						}
						if(!AclUtil.filterTimeInfo(timeInfoList.get(i))){
							errorCount++;	
							timeInfoResult.add(new String[]{"acl_group_timeInfo_import_failed_filter",new Integer(i+1).toString(),"acl_group_timeInfo_failed_error"});
							continue;
						}
						tempTimeInfo.add(timeInfoList.get(i));
					}
					//保存所有TimeInfo
					for(TimeInfo timeInfo : tempTimeInfo){
						timeInfo.setTimeRange(entity);
						timeInfoService.save(timeInfo);
					}
					String success= new Integer(allTimeInfoCount-errorCount).toString();//成功的timeInfo条数
					validaterInfos.add(new String[]{"acl_group_timeRange_import_info",entity.getName(),success,new Integer(errorCount).toString()});
					if(timeInfoResult!=null&&timeInfoResult.size()>0){
						validaterInfos.addAll(timeInfoResult);
					}
					
				}
			}
		}
		return validaterInfos;
	}
		
	/**
	 * ACL组名称重复验证



	 * 
	 * @param name
	 *            ACL组名称



	 * @param id
	 *            本身的ID
	 * @return true or false
	 */
	public boolean isExistGroupName(String name, Long id) {
		Assert.notNull(name);
		Criteria criteria = createCriteria(AccessGroup.class);
		criteria.add(Restrictions.eq("name", name));
		criteria.add(Restrictions.isNull("aclDevice"));
		// 如果ID号 != null ,则表示为修改，如果ID号 == null ，则为添加

		if (id != null) {
			Criterion idCriterion = Restrictions.not(Restrictions.eq("id", id));
			criteria.add(idCriterion);
		}
		int totalCount = (Integer) criteria.setProjection(
				Projections.rowCount()).uniqueResult();
		// 如果都没有被使用,返回False
		if (totalCount == 0) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * 取得ACL组的所有信息，包括ACE的列表



	 * 
	 * @param accessGroup
	 *            组信息



	 * @return 组信息



	 */
	public AccessGroup getDetail(AccessGroup accessGroup) {
		Assert.notNull(accessGroup);
		if (accessGroup.getId() == null || accessGroup.getId() == 0) {
			return accessGroup;
		}
		accessGroup = get(accessGroup.getId());
		accessGroup.getAces();
		return accessGroup;
	}

	/**
	 * 根据名称取得ACL组信息



	 * 
	 * @param name
	 *            ACl组名称



	 * 
	 * @return List 组信息



	 */
	@SuppressWarnings("unchecked")
	public List<AccessGroup> getAccessGroupByName(String name) {
		Assert.notNull(name);
		Criteria criteria = createCriteria(AccessGroup.class);
		criteria.add(Restrictions.eq("name", name));
		List<AccessGroup> list = criteria.list();
		return list;
	}

	/**
	 * 根据名称取得无ACL设备的ACL组信息



	 * 
	 * @param name
	 *            ACL组名称



	 * @param aclDevice
	 * 			  ACL设备
	 * 
	 * @return ACL组信息



	 */
	@SuppressWarnings("unchecked")
	public AccessGroup getByNameWithAclDevice(String name, AclDevice aclDevice) {
		Assert.notNull(aclDevice);
		if (name == null){
			return null;
		}
		AccessGroup accessGroupDevice = null;
		Criteria criteria = createCriteria(AccessGroup.class);
		criteria.add(Restrictions.eq("name", name));
		criteria.add(Restrictions.eq("aclDevice", aclDevice));
		List<AccessGroup> list = criteria.list();
		if (list != null && list.size() > 0){
			accessGroupDevice = list.get(0);
		}
		return accessGroupDevice;
	}
	/**
	 * 根据名称取得无ACL设备的ACL组信息
	 * 
	 * @param name
	 *            ACl组名称
	 * 
	 * @return ACL组信息
	 */
	@SuppressWarnings("unchecked")
	public AccessGroup getByNameWithoutAclDevice(String name) {
		if (name == null){
			return null;
		}
		AccessGroup accessGroupSystem = null;
		List<AccessGroup> list = getAccessGroupByName(name);
		if (list != null && list.size() > 0){
			for (AccessGroup entity : list){
				if (entity.getAclDevice() == null){
					accessGroupSystem = entity;
					break;
				}
			}
		}
		return accessGroupSystem;
	}
	
	/**
	 * 根据名称取得无ACL设备的ACL组信息，如果该组没有和该设备关联返回NULL
	 * 
	 * @param name
	 *            ACl组名称
	 * 
	 * @return ACL组信息
	 */
	@SuppressWarnings("unchecked")
	public AccessGroup getByNameWithoutAclDevice(String name,AclDevice aclDevice) {
		if (name == null){
			return null;
		}
		AccessGroup accessGroup = getByNameWithAclDevice(name,aclDevice);
		if(accessGroup == null){
			return null;
		}
		AccessGroup accessGroupSystem = null;
		List<AccessGroup> list = getAccessGroupByName(name);
		if (list != null && list.size() > 0){
			for (AccessGroup entity : list){
				if (entity.getAclDevice() == null){
					accessGroupSystem = entity;
					break;
				}
			}
		}
		return accessGroupSystem;
	}
	
	

	/**
	 * 分页查询可选择的ACL组



	 * 
	 * @param ids
	 *            已经选择的ACL组id列表
	 * @param accessGroup
	 *            筛选条件



	 * @param pageNo
	 *            页数
	 * @param pageSize
	 *            每页显示的记录数
	 * @return ACL组列表



	 */
	public Page pagedQueryAvailableAccessGroups(Object[] ids,
			AccessGroup accessGroup, int pageNo, int pageSize) {
		Criteria criteria = createCriteria(AccessGroup.class);
		criteria.add(Restrictions.isNull("aclDevice"));
		if (!StringUtils.isNullOrEmpty(accessGroup.getName())) {
			Criterion nameCriterion = Restrictions.like("name", accessGroup
					.getName(), MatchMode.ANYWHERE);
			criteria.add(nameCriterion);
		}
		if (!StringUtils.isNullOrEmpty(accessGroup.getAclType())) {
			Criterion genreCriterion = Restrictions.eq("aclType", accessGroup
					.getAclType());
			criteria.add(genreCriterion);
		}
		if (ids != null && ids.length > 0) {
			criteria.add(Restrictions.not(Restrictions.in("id", ids)));
		}
		return pagedQuery(criteria, pageNo, pageSize);
	}

	/**
	 * 分页查询已经选择的ACL组



	 * 
	 * @param ids
	 *            已经选择的ACL组id列表
	 * @param pageNo
	 *            页数
	 * @param pageSize
	 *            每页显示的记录数
	 * @return ACL组列表



	 */
	public Page pagedQuerySelectedAccessGroups(Object[] ids, int pageNo,
			int pageSize) {
		Criteria criteria = createCriteria(AccessGroup.class);
		if (ids == null || ids.length == 0) {
			ids = new Long[1];
			ids[0] = -1L;
		}
		criteria.add(Restrictions.in("id", ids));
		criteria.add(Restrictions.isNull("aclDevice"));
		return pagedQuery(criteria, pageNo, pageSize);
	}
	
	private void removeAceByAccessGroup(AccessGroup entity) {
		String hql = "delete from Ace where accessGroup = ?";
		createQuery(hql, entity).executeUpdate();
	}
	
	private void removeAclDeviceByAccessGroup(AccessGroup entity) {
		String hql = "delete from AclDeviceAccessGroup where accessGroup = ?";
		createQuery(hql, entity).executeUpdate();
	}
	
	/**
	 * 判断acl组是否与设备关联
	 * @param entity
	 * @return
	 */
	public boolean isRelated2Device(AccessGroup entity){
		Criteria criteriaDeviceTimeRange = createCriteria(AclDeviceAccessGroup.class);
		criteriaDeviceTimeRange.add(Restrictions.eq("accessGroup", entity));
		int result = (Integer) criteriaDeviceTimeRange.setProjection(Projections.rowCount()).uniqueResult();
		return result>0;
	}

	/**
	 * 通过acl组删除aclInterface
	 * @param entity
	 */
	public void removeAclInterface(AccessGroup entity){
		String hql="";
		List<AccessGroup> accessGroupList = new ArrayList<AccessGroup>();
		accessGroupList.add(entity);
		List<AclInterface> aclDeviceList = aclInterfaceService.findByAccessGroup(accessGroupList);
		for(AclInterface aclInterface:aclDeviceList){
			String inputName = aclInterface.getInAccessGroupName();
			String outputName = aclInterface.getOutAccessGroupName();
			if(entity.getName().equals(inputName) &&
					 !entity.getName().equals(outputName)&&
					 outputName!=null){
				hql = "update AclInterface set inAccessGroup = null ,inAccessGroupName = null where inAccessGroup=?";
			}else if(entity.getName().equals(outputName) &&
					!entity.getName().equals(inputName)&&
					inputName!=null){
				hql = "update AclInterface set outAccessGroup = null ,outAccessGroupName = null where outAccessGroup=?";
			}else{
				hql = "delete AclInterface where inAccessGroup=?";
				createQuery(hql, entity).executeUpdate();
				break;
			}
			createQuery(hql, entity).executeUpdate();
		}
	}
	
	/**
	 * 通过acl组删除aclInterface
	 * @param entity
	 */
	public void removeAclInterface(AccessGroup entity,Device device){
		String hql="";
		List<AccessGroup> accessGroupList = new ArrayList<AccessGroup>();
		accessGroupList.add(entity);
		List<Object> paramList = new ArrayList<Object>();
		List<AclInterface> aclDeviceList = aclInterfaceService.getAclInterfaces(device,entity);
		for(AclInterface aclInterface:aclDeviceList){
			String inputName = aclInterface.getInAccessGroupName();
			String outputName = aclInterface.getOutAccessGroupName();
			if(entity.getName().equals(inputName) &&
					 !entity.getName().equals(outputName)&&
					 outputName!=null){
				hql = "update AclInterface set inAccessGroup = null ,inAccessGroupName = null where inAccessGroup=? and device=?";
			}else if(entity.getName().equals(outputName) &&
					!entity.getName().equals(inputName)&&
					inputName!=null){
				hql = "update AclInterface set outAccessGroup = null ,outAccessGroupName = null where outAccessGroup=? and device=?";
			}else{
				hql = "delete AclInterface where inAccessGroup=? and device=?";
				paramList.add(entity);
				paramList.add(device);
				createQuery(hql, paramList.toArray()).executeUpdate();
				break;
			}
			paramList.add(entity);
			paramList.add(device);
			createQuery(hql, paramList.toArray()).executeUpdate();
		}
	}
	
	/**
	 * 删除与指定ACL组对应的所有设备ACL组


	 * @param entity ACL组


	 */
	public void removeWithAclDevice(AccessGroup entity){
		if (entity.getAclDevice() == null){
			String hql = "delete from Ace where accessGroup.id in (select ag.id from AccessGroup ag where ag.name = ? and ag.aclDevice is not null)";
			createQuery(hql, entity.getName()).executeUpdate();
			hql = "delete from AclDeviceAccessGroup where accessGroup.id in (select ag.id from AccessGroup ag where ag.name = ? and ag.aclDevice is not null)";
			createQuery(hql, entity.getName()).executeUpdate();
			List<AccessGroup> list = getAccessGroupByName(entity.getName());
			if (list != null && list.size() > 0){
				for (AccessGroup ag : list){
					if (ag.getAclDevice() != null){
						removeAclInterface(ag);
					}
				}
			}
			hql = "delete from AccessGroup where name = ? and aclDevice is not null";
			createQuery(hql, entity.getName()).executeUpdate();
		}
	}

	@Override
	public void remove(AccessGroup entity) {
		removeWithAclDevice(entity);
		removeAceByAccessGroup(entity);
		removeAclDeviceByAccessGroup(entity);
		removeAclInterface(entity);
		super.remove(entity);
	}
	
	/**
	 * ACL组详细界面的单设备部署




	 * @param id
	 * @param device
	 */
	public void reConfig(AccessGroup accessGroup,Device device,String dealFlag){		
			PlanParameters parameters = new PlanParameters();
			List<AccessGroup> accessGroupList = new ArrayList<AccessGroup>();
			accessGroupList.add(accessGroup);
			/*存入accessGroupInfoList*/
			List<AccessGroupInfo> accessGroupInfoList = aceService.accessGroup2AccessGroupInfo(accessGroupList);
			parameters.putParameter("accessGroupInfoList", accessGroupInfoList);
			/*存入AclInterfaceInfoList*/
			List<AclInterface> aclInterfaceList = aclInterfaceService.getAclInterfaces(device,accessGroup);
			List<AclInterfaceInfo> aclInterfaceInfos = AclConfigUtil.aclInterfaceList2AclInterfaceInfoList(aclInterfaceList,accessGroup);
			parameters.putParameter("aclInterfaceInfoList", aclInterfaceInfos);
			
			/*存入DealType*/
			parameters.putParameter("dealFlag",dealFlag);
			taskConfigAclDevice.processItem(device, parameters);	
			AclDevice aclDevice = aclDeviceService.getByDevice(device);
			updateChangeFlag(accessGroup, aclDevice);
			if (!"DeleteAccessGroup".equals(dealFlag)){
				//创建新的ACL组(设备)信息
				this.saveSameWithAclDevice(accessGroup, aclDevice, null);
				
				deviceTimeRangeService.saveAclDeviceTimeRange(accessGroup, aclDevice.getDevice());
			}
	}
	
	/**
	 * 获得接口名，inout,组名
	 * @param devices
	 * @param accessGroup
	 * @return
	 */
	public String getInterfaceNames(Device devices,AccessGroup accessGroup){
		List<AclInterface> aclDeviceList = aclInterfaceService.getAclInterfaces(devices,accessGroup);
		String str = "";
		for(AclInterface aclInterface:aclDeviceList){
			str +=";"+AclUtil.escapeSpecialString(aclInterface.getDeviceInterface().getName())+",";
			String inputName = aclInterface.getInAccessGroupName();
			String outputName = aclInterface.getOutAccessGroupName();
			if(!StringUtils.isNullOrEmpty(inputName) && 
						!StringUtils.isNullOrEmpty(outputName)){
				str +="InOut,";
			}else if(!StringUtils.isNullOrEmpty(inputName) && 
					  StringUtils.isNullOrEmpty(outputName)){
				str +="In,";
			}else{
				str +="Out,";
			}
			str += AclUtil.escapeSpecialString(accessGroup.getName());
		}
		if (str.length() > 0){
			str = str.substring(1);
		}
		return str;
	}
	
	/**
	 * 获得接口名，inout,组名
	 * @param devices
	 * @param accessGroup
	 * @return
	 */
	public String getInterfaceIds(Device devices,AccessGroup accessGroup){
		List<AclInterface> aclDeviceList = aclInterfaceService.getAclInterfaces(devices,accessGroup);
		String str = "";
		for(AclInterface aclInterface:aclDeviceList){
			str +=";"+aclInterface.getDeviceInterface().getId()+",";
			String inputName = aclInterface.getInAccessGroupName();
			String outputName = aclInterface.getOutAccessGroupName();
			if(!StringUtils.isNullOrEmpty(inputName) && 
						!StringUtils.isNullOrEmpty(outputName)){
				str +="InOut,";
			}else if(!StringUtils.isNullOrEmpty(inputName) && 
					  StringUtils.isNullOrEmpty(outputName)){
				str +="In,";
			}else{
				str +="Out,";
			}
			str += accessGroup.getId();
		}
		if (str.length() > 0){
			str = str.substring(1);
		}
		return str;
	}
	
	/**
	 * 根据时间段列表取得与之相关的组信息



	 * @return 组列表



	 */
	@SuppressWarnings("unchecked")
	public List<AccessGroup> findByTimeRange(List<TimeRange> timeRangeList){
		Assert.notEmpty(timeRangeList);
		Criteria criteria = createCriteria(AccessGroup.class);
		
		DetachedCriteria subselect = DetachedCriteria.forClass(Ace.class);
		subselect.setProjection(Property.forName("accessGroup.id"));
		subselect.add(Restrictions.in("timeRange", timeRangeList));

		criteria.add(Property.forName("id").in(subselect));
		
		return criteria.list();
	}
	
	/**
	 * <p>根据ID字符串取得ACL组信息</p>
	 * <p>ID字符串使用逗号(,)分隔</p> 
	 * @return ACL组信息列表



	 */
	public List<AccessGroup> findByIds(String ids){
		Assert.hasText(ids);
		String[] arrIds = ids.split(",");
		List<Long> idList = new ArrayList<Long>();
		for(String id : arrIds){
			if (id.trim().length() > 0){
				idList.add(Long.parseLong(id));
			}
		}
		return this.findByIds(idList.toArray(new Long[idList.size()]));
	}
	
	/**
	 * 通过时间组获得device
	 * @param entity时间组



	 * @return device
	 */
	@SuppressWarnings("unchecked")
	public List<Device> getDevices(AccessGroup entity){
		Criteria criteria = createCriteria(AclDeviceAccessGroup.class);
		criteria.add(Restrictions.eq("accessGroup", entity));
		List<AclDeviceAccessGroup> list = criteria.list();
		List<Device> deviceList = new ArrayList<Device>();
		for(AclDeviceAccessGroup accessGroup:list){
			Device device = accessGroup.getAclDevice().getDevice();
			deviceList.add(device);
		}
		return deviceList;
	}
	
	/**
	 * <p>根据ID数组取得ACL组信息</p>
	 * @return ACL组信息列表



	 */
	@SuppressWarnings("unchecked")
	public List<AccessGroup> findByIds(Long[] ids){
		Assert.notNull(ids);
		Criteria criteria = createCriteria(AccessGroup.class);
		criteria.add(Restrictions.in("id", ids));
		return criteria.list();
	}

	/**
	 * 根据设备取得与之关联的ACL组信息列表



	 * @param device　ACL设备
	 * @return　组信息列表



	 */
	@SuppressWarnings("unchecked")
	public List<AccessGroup> findByDevice(Device device){
		Assert.notNull(device);
		AclDevice aclDevice = this.findUniqueBy(AclDevice.class, "device", device);
		Criteria criteria = createCriteria(AccessGroup.class);
		
		DetachedCriteria subselect = DetachedCriteria.forClass(AclDeviceAccessGroup.class);
		subselect.setProjection(Property.forName("accessGroup.id"));
		subselect.add(Restrictions.eq("aclDevice", aclDevice));
		criteria.add(Property.forName("id").in(subselect));
		return criteria.list();
	}
	
	public TimeRangeService getTimeRangeService() {
		return timeRangeService;
	}

	public void setTimeRangeService(TimeRangeService timeRangeService) {
		this.timeRangeService = timeRangeService;
	}

	public TimeInfoService getTimeInfoService() {
		return timeInfoService;
	}

	public void setTimeInfoService(TimeInfoService timeInfoService) {
		this.timeInfoService = timeInfoService;
	}

	public AceService getAceService() {
		return aceService;
	}

	public void setAceService(AceService aceService) {
		this.aceService = aceService;
	}

	public AclPlanParametersService getParametersService() {
		return parametersService;
	}

	public void setParametersService(AclPlanParametersService parametersService) {
		this.parametersService = parametersService;
	}

	public TaskConfigAclDevice getTaskConfigAclDevice() {
		return taskConfigAclDevice;
	}

	public void setTaskConfigAclDevice(TaskConfigAclDevice taskConfigAclDevice) {
		this.taskConfigAclDevice = taskConfigAclDevice;
	}
	/**
	 * 删除与指定ACL组同名且包含ACL设备的记录

	 * @param entity ACL组

	 */
	public void updateChangeFlag(AccessGroup entity, AclDevice aclDevice){
		//修改多对多关系的修改标志位
		AclDeviceAccessGroup deviceAccessGroup = deviceAccessGroupService.getByAclDeviceAndAccessGroup(aclDevice, entity);
		if (deviceAccessGroup != null &&  deviceAccessGroup.getIsChanged()){
			deviceAccessGroup.setIsChanged(false);
			deviceAccessGroupService.update(deviceAccessGroup);
		}
		//更新ACL组的修改标志位
		if (entity.getIsChanged() && !deviceAccessGroupService.existByAccessGroupAndChanged(entity)){
			entity.setIsChanged(false);
			this.update(entity);
		}
		
	}

	public DeviceAccessGroupService getDeviceAccessGroupService() {
		return deviceAccessGroupService;
	}

	public void setDeviceAccessGroupService(
			DeviceAccessGroupService deviceAccessGroupService) {
		this.deviceAccessGroupService = deviceAccessGroupService;
	}
	/**
	 * 保存与指定ACL组列表且包含指定设备对应的ACL设备的ACL组
	 * @param entityList ACL组列表
	 * @param device 设备
	 */
	public void saveSameWithDevice(List<AccessGroup> entityList, Device device){
		if (entityList != null && entityList.size() > 0){
			AclDevice aclDevice = aclDeviceService.getByDevice(device);
			if (aclDevice != null){
				for (AccessGroup entity : entityList){
					saveSameWithAclDevice(entity, aclDevice, null);
				}
			}
		}
	}
	/**保存与指定ACL组相同信息且包含ACL设备的ACL组

	 * @param entity ACL组

	 * @param aclDevice ACL设备
	 * @param aceList 规则列表
	 */
	public void saveSameWithAclDevice(AccessGroup entity, AclDevice aclDevice, List<Ace> aceList){
		Assert.notNull(entity);
		Assert.notNull(aclDevice);
		//判断是否存在,不存在则新建
		AccessGroup newEntity = this.getByNameWithAclDevice(entity.getName(),aclDevice);
		//删除原ACE信息
		if (newEntity != null && newEntity.getAclDevice() != null && newEntity.getId() != null){
			aceService.deleteByAccessGroup(newEntity);
		}
		newEntity = entity.clone(newEntity, aclDevice);
		this.save(newEntity);
		//保存新ACE信息,但若为null保存源ACL组的ACE列表
		if (aceList == null){
			List<Ace> sourceAceList = aceService.getByAccessGroup(entity);
			if (sourceAceList != null && sourceAceList.size() > 0){
				for (Ace ace : sourceAceList){
					Ace aceEntity = ace.clone(newEntity);
					aceService.save(aceEntity);
				}
			}
		}else if (aceList != null && aceList.size() > 0){
			for (Ace ace : aceList){
				Ace aceEntity = ace.clone(newEntity);
				aceService.save(aceEntity);
			}
		}
	}

	public AclDeviceService getAclDeviceService() {
		return aclDeviceService;
	}

	public void setAclDeviceService(AclDeviceService aclDeviceService) {
		this.aclDeviceService = aclDeviceService;
	}

	public DeviceTimeRangeService getDeviceTimeRangeService() {
		return deviceTimeRangeService;
	}

	public void setDeviceTimeRangeService(DeviceTimeRangeService deviceTimeRangeService) {
		this.deviceTimeRangeService = deviceTimeRangeService;
	} 
	/**
	 * 更新ACL组的修改标志位
	 * @param list ACL组列表
	 */
	public void updateChangeFlagByAccessGroupList(List<AccessGroup> list){
		if (list != null && list.size() > 0){
			for (AccessGroup entity : list){
				updateChangeFlag(entity);
			}
		}
	}
	/**
	 * 更新ACL组修改标志位
	 * @param entity ACL组
	 */
	public void updateChangeFlag(AccessGroup entity){
		//更新ACL组的修改标志位
		if (entity.getIsChanged() && !deviceAccessGroupService.existByAccessGroupAndChanged(entity)){
			entity.setIsChanged(false);
			this.update(entity);
		}
	}
	/**
	 * 取得包含指定ACL设备的ACL组列表
	 * @param aclDevice ACL设备
	 * @return ACL组列表
	 */
	@SuppressWarnings("unchecked")
	public List<AccessGroup> getByAclDevice(AclDevice aclDevice){
		Assert.notNull(aclDevice);
		List<AccessGroup> list = new ArrayList<AccessGroup>();
		Criteria criteria = createCriteria(AccessGroup.class);
		criteria.add(Restrictions.eq("aclDevice", aclDevice));
		list = criteria.list();
		return list;
	}
}
